package com.itheima.manage.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.commons.pojo.domain.UserInfo;
import com.itheima.commons.pojo.entity.PublishCheckLog;
import com.itheima.commons.pojo.entity.PublishInfo;
import com.itheima.commons.pojo.mongo.Publish;
import com.itheima.commons.vo.backstage.*;
import com.itheima.dubbo.interfaces.*;
import com.itheima.manage.excepiton.BusinessException;
import com.itheima.manage.excepiton.ErrorResult;
import com.itheima.manage.interceptor.AdminThreadLocal;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.*;

/**
 * @author yaohu
 * @version 1.0
 * @date 2021/12/18
 */
@Service
public class MessageService {

    @Reference
    private PublishApi publishApi;

    @Reference
    private PublishInfoApi publishInfoApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Reference
    private CommentApi commentApi;

    @Reference
    private PublishCheckLogApi publishCheckLogApi;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 消息翻页
     *
     * @param pagesize  页尺寸
     * @param page      页数
     * @param likeId    消息id
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param state     审核状态
     * @return
     */
    public PageResult messages(Integer pagesize, Integer page, Integer likeId, String startDate, String endDate, String state) {
        List<PublishInfo> publishInfoList;

        // 计总条数
        int count;

        switch (state) {
            case "1":
                // 全部
                publishInfoList = publishInfoApi.queryAllPublishInfo(pagesize, page, likeId, startDate, endDate);
                count = publishInfoApi.queryCount(1, likeId, startDate, endDate);
                break;
            case "2":
                // 待审核
                publishInfoList = publishInfoApi.queryWaitToCheck(pagesize, page, likeId, startDate, endDate);
                count = publishInfoApi.queryCount(2, likeId, startDate, endDate);
                break;
            case "3":
                // 已通过
                publishInfoList = publishInfoApi.queryPassPublishInfo(pagesize, page, likeId, startDate, endDate);
                count = publishInfoApi.queryCount(3, likeId, startDate, endDate);
                break;
            case "4":
                // 已拒绝
                publishInfoList = publishInfoApi.queryRefusePublishInfo(pagesize, page, likeId, startDate, endDate);
                count = publishInfoApi.queryCount(4, likeId, startDate, endDate);
                break;
            default:
                throw new BusinessException(ErrorResult.parameterError());
        }

        if (CollUtil.isEmpty(publishInfoList)) {
            return new PageResult(page, pagesize, 0L, Collections.emptyList(), Collections.emptyList());
        }

        List<Long> userIds = CollUtil.getFieldValues(publishInfoList, "userId", Long.class);

        Map<Long, UserInfo> userInfoMap = userInfoApi.findUserInfoByUserIds(userIds);
        // 拼凑vo
        List<PublishInfoVo> publishInfoVoList = new ArrayList<>();
        List<TotalVo> totalVoList = new ArrayList<>();

        for (PublishInfo publishInfo : publishInfoList) {
            PublishInfoVo publishInfoVo = new PublishInfoVo();

            publishInfoVo.setState(publishInfo.getState());
            publishInfoVo.setCreateDate(publishInfo.getCreated());
            publishInfoVo.setReportCount(0);
            publishInfoVo.setReportCount(publishInfo.getReportCount());
            publishInfoVo.setLikeCount(publishInfo.getLikeCount());
            publishInfoVo.setCommentCount(publishInfo.getCommentCount());
            publishInfoVo.setForwardingCount(publishInfo.getForwardingCount());

            UserInfo userInfo = userInfoMap.get(publishInfo.getUserId());
            publishInfoVo.setId(Convert.toStr(publishInfo.getId()));
            publishInfoVo.setNickname(userInfo.getNickName());
            publishInfoVo.setUserId(Convert.toInt(userInfo.getUserId()));
            publishInfoVo.setUserLogo(userInfo.getLogo());

            Publish publish = publishApi.queryPublishById(publishInfo.getPublishId());
            publishInfoVo.setText(publish.getText());
            if (publish.getMedias().size() >= 3) {
                publishInfoVo.setMedias(publish.getMedias().subList(0, 3));
            } else {
                publishInfoVo.setMedias(publish.getMedias());
            }

            publishInfoVoList.add(publishInfoVo);
        }

        TotalVo totalVo1 = new TotalVo();
        totalVo1.setTitle("全部");
        totalVo1.setCode("1");
        totalVo1.setValue(publishInfoApi.queryTotal(1));
        totalVoList.add(totalVo1);

        TotalVo totalVo2 = new TotalVo();
        totalVo2.setTitle("待审核");
        totalVo2.setCode("2");
        totalVo2.setValue(publishInfoApi.queryTotal(2));
        totalVoList.add(totalVo2);

        TotalVo totalVo3 = new TotalVo();
        totalVo3.setTitle("已通过");
        totalVo3.setCode("3");
        totalVo3.setValue(publishInfoApi.queryTotal(3));
        totalVoList.add(totalVo3);

        TotalVo totalVo4 = new TotalVo();
        totalVo4.setTitle("已驳回");
        totalVo4.setCode("4");
        totalVo4.setValue(publishInfoApi.queryTotal(4));
        totalVoList.add(totalVo4);

        return new PageResult(page, pagesize, Convert.toLong(count), publishInfoVoList, totalVoList);
    }

    /**
     * 查询审核通过的个人圈子信息及排序
     *
     * @param page      当前页码
     * @param pagesize  每页页数
     * @param sortProp  排序字段 reportCount likeCount commentCount forwardingCount 默认createDate
     * @param sortOrder 排序规则 ascending 默认descending
     * @param userId    用户id
     * @return
     */
    public PageResult passPublishList(Integer page, Integer pagesize, String sortProp, String sortOrder, String userId) {

        // 查询全部通过的圈子信息
        List<PublishInfo> publishInfoList = publishInfoApi.queryAllPublishByUserId(pagesize, page, userId, sortProp, sortOrder);

        if (CollUtil.isEmpty(publishInfoList)) {
            return new PageResult(page, pagesize, 0L, Collections.emptyList(), Collections.emptyList());
        }

        List<PublishInfoVo> publishInfoVoList = new ArrayList<>();

        for (PublishInfo publishInfo : publishInfoList) {
            PublishInfoVo publishInfoVo = new PublishInfoVo();

            publishInfoVo.setId(publishInfo.getId().toString());
            publishInfoVo.setState(publishInfo.getState());
            publishInfoVo.setReportCount(publishInfo.getReportCount());
            publishInfoVo.setLikeCount(publishInfo.getLikeCount());
            publishInfoVo.setCommentCount(publishInfo.getCommentCount());
            publishInfoVo.setForwardingCount(publishInfo.getForwardingCount());

            UserInfo userInfo = userInfoApi.findUserInfoByUserId(publishInfo.getUserId());
            publishInfoVo.setNickname(userInfo.getNickName());
            publishInfoVo.setUserId(Convert.toInt(userId));
            publishInfoVo.setUserLogo(userInfo.getLogo());
            publishInfoVo.setCreateDate(publishInfo.getCreated());

            Publish publish = publishApi.queryPublishById(publishInfo.getPublishId());
            publishInfoVo.setText(publish.getText());
            if (publish.getMedias().size() >= 3) {
                publishInfoVo.setMedias(publish.getMedias().subList(0, 3));
            } else {
                publishInfoVo.setMedias(publish.getMedias());
            }

            publishInfoVoList.add(publishInfoVo);
        }

        Long count = Convert.toLong(publishInfoApi.countAllPublishByUserId(userId));

        return new PageResult(page, pagesize, count, publishInfoVoList, Collections.emptyList());
    }

    /**
     * 获取ip地址
     *
     * @return ip地址
     */
    private String getAddress() {
        String hostAddress;
        try {
            hostAddress = Inet4Address.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            throw new BusinessException(ErrorResult.getIPError());
        }
        return hostAddress;
    }

    /**
     * 记录审核日志
     *
     * @param ids 多选publishInfoId
     * @param msg 操作内容
     */
    private void saveCheckLog(List<String> ids, String msg) {
        // 查询多选信息
        List<PublishInfo> publishInfoList = publishInfoApi.queryPublishInfoByIds(ids);

        for (PublishInfo publishInfo : publishInfoList) {
            PublishCheckLog publishCheckLog = new PublishCheckLog();

            publishCheckLog.setPublishId(publishInfo.getPublishId());
            publishCheckLog.setAdmin(AdminThreadLocal.getAdminUsername());
            publishCheckLog.setIp(getAddress());

            publishCheckLog.setOperation(msg);
            publishCheckLog.setContent(msg + "【" + publishInfo.getUserId() + "】");
            publishCheckLog.setCreated(new Date());

            // 发送消息
            rocketMQTemplate.convertAndSend("check_log", publishCheckLog);
        }
    }

    /**
     * 人工审核通过 5
     *
     * @param ids 审核消息id
     */
    public Boolean messagesPass(List<String> ids) {
        Integer count = publishInfoApi.passPublishByIds(ids);

        String msg = "人工审核通过";
        saveCheckLog(ids, msg);

        return count != 0;
    }

    /**
     * 人工审核拒绝 4
     *
     * @param ids 审核消息id
     * @return
     */
    public Boolean messagesReject(List<String> ids) {
        Integer count = publishInfoApi.rejectPublishByIds(ids);

        String msg = "人工审核拒绝";
        saveCheckLog(ids, msg);

        return count != 0;
    }

    /**
     * 人工审核撤销 3
     *
     * @param ids 审核消息id
     * @return
     */
    public Boolean messagesRevocation(List<String> ids) {
        Integer count = publishInfoApi.revocationPublishByIds(ids);

        String msg = "人工审核撤销";
        saveCheckLog(ids, msg);

        return count != 0;
    }

    /**
     * 消息详情
     *
     * @param publishInfoId
     * @return
     */
    public MessageVo messageDetails(String publishInfoId) {
        // 1.查询publishInfo
        PublishInfo publishInfo = publishInfoApi.queryPublishInfoById(publishInfoId);
        // 2.获取userInfo、publish
        UserInfo userInfo = userInfoApi.findUserInfoByUserId(publishInfo.getUserId());
        Publish publish = publishApi.queryPublishById(publishInfo.getPublishId());
        // 封装vo
        MessageVo messageVo = new MessageVo();
        // 圈子id
        messageVo.setId(publish.getId().toHexString());
        messageVo.setNickname(userInfo.getNickName());
        messageVo.setUserId(Convert.toInt(userInfo.getUserId()));
        messageVo.setUserLogo(userInfo.getLogo());
        // 圈子发布时间
        messageVo.setCreateDate(publish.getCreated());
        messageVo.setText(publish.getText());
        if (publish.getMedias().size() >= 3) {
            messageVo.setMedias(publish.getMedias().subList(0, 3));
        } else {
            messageVo.setMedias(publish.getMedias());
        }
        messageVo.setState(Convert.toInt(publishInfo.getState()));
        messageVo.setTopState(publishInfo.getIstop());
        messageVo.setCommentCount(Convert.toInt(commentApi.queryCommentCount(publishInfo.getPublishId())));
        messageVo.setLikeCount(Convert.toInt(commentApi.queryLikeCount(publishInfo.getPublishId())));
        // 举报数
        messageVo.setReportCount(0);
        // 转发数
        messageVo.setForwardingCount(Convert.toInt(commentApi.queryLoveCount(publishInfo.getPublishId())));
        return messageVo;
    }

    /**
     * 记录单条日志
     *
     * @param publishInfoId 审核消息id
     * @param msg           操作内容
     */
    private void saveCheckLog(String publishInfoId, String msg) {
        // 查询审核消息内容
        PublishInfo publishInfo = publishInfoApi.queryPublishInfoById(publishInfoId);

        PublishCheckLog publishCheckLog = new PublishCheckLog();

        publishCheckLog.setPublishId(publishInfo.getPublishId());
        publishCheckLog.setAdmin(AdminThreadLocal.getAdminUsername());
        publishCheckLog.setIp(getAddress());
        publishCheckLog.setOperation(msg);
        publishCheckLog.setContent(msg + "【" + publishInfo.getPublishId() + "】");
        publishCheckLog.setCreated(new Date());
        // 发送消息
        rocketMQTemplate.convertAndSend("check_log", publishCheckLog);
    }

    /**
     * 消息置顶
     *
     * @param publishInfoId
     * @return
     */
    public Boolean messageTop(String publishInfoId) {
        Integer count = publishInfoApi.topPublishInfoById(publishInfoId);

        String msg = "消息置顶";
        saveCheckLog(publishInfoId, msg);

        return count != 0;
    }

    /**
     * 消息取消置顶
     *
     * @param publishInfoId
     * @return
     */
    public Boolean messageUnTop(String publishInfoId) {
        Integer count = publishInfoApi.unTopPublishInfoById(publishInfoId);

        String msg = "消息取消置顶";
        saveCheckLog(publishInfoId, msg);

        return count != 0;
    }

    /**
     * 分页查询审核日志记录
     *
     * @param page      当前页
     * @param pagesize  每页条数
     * @param username  操作人
     * @param operation 操作内容
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public PageResult findCheckLog(Integer page, Integer pagesize, String username, String operation, String startTime, String endTime) {
        List<PublishCheckLog> publishCheckLogList = publishCheckLogApi.findCheckLog(
                page, pagesize, username, operation, startTime, endTime);

        if (CollUtil.isEmpty(publishCheckLogList)) {
            return new PageResult(page, pagesize, 0L, Collections.emptyList(), Collections.emptyList());
        }

        List<PublishCheckLogVo> publishCheckLogVoList = new ArrayList<>();

        for (PublishCheckLog publishCheckLog : publishCheckLogList) {
            PublishCheckLogVo publishCheckLogVo = new PublishCheckLogVo();

            publishCheckLogVo.setId(publishCheckLog.getId());
            publishCheckLogVo.setAdminName(publishCheckLog.getAdmin());
            publishCheckLogVo.setIp(publishCheckLog.getIp());
            publishCheckLogVo.setTime(publishCheckLog.getCreated());
            publishCheckLogVo.setOperation(publishCheckLog.getOperation());
            publishCheckLogVo.setContent(publishCheckLog.getContent());

            publishCheckLogVoList.add(publishCheckLogVo);
        }

        return new PageResult(page, pagesize, Convert.toLong(publishCheckLogVoList.size()), publishCheckLogVoList, Collections.emptyList());
    }

    /**
     * 生成tb_publish_info内容
     */
    public void messageCreate() {
        // 查询全部publishInfo
        List<PublishInfo> publishInfoList = publishInfoApi.findAll();
        // 获取对应的publishId
        List<String> publishIds = CollUtil.getFieldValues(publishInfoList, "publishId", String.class);
        // 查找不在publish_info表中的publish
        List<Publish> publishList = publishApi.findOthers(publishIds);

        for (Publish publish : publishList) {
            PublishInfo publishInfo = new PublishInfo();
            // 不传自增
            // publishInfo.setId(0L);
            publishInfo.setPublishId(publish.getId().toHexString());
            // 默认机器审核通过
            publishInfo.setState("2");
            // 默认未置顶
            publishInfo.setIstop(1);
            publishInfo.setUserId(publish.getUserId());
            publishInfo.setReportCount(0);
            publishInfo.setLikeCount(Convert.toInt(commentApi.queryLikeCount(publish.getId().toHexString()), 0));
            publishInfo.setCommentCount(Convert.toInt(commentApi.queryCommentCount(publish.getId().toHexString()), 0));
            publishInfo.setForwardingCount(Convert.toInt(commentApi.queryLoveCount(publish.getId().toHexString()), 0));
            publishInfo.setCreated(publish.getCreated());
            publishInfo.setUpdated(publish.getCreated());

            publishInfoApi.savePublishInfo(publishInfo);
        }
    }
}
